local zylib = require("zylib")

-- 在脉冲索引表中匹配指定的脉冲
-- @param pwt 脉冲宽度表
-- @param pwtn 
local matchPulse(pwt, pwtn, pwerr, pulse)
	local err

	-- 在当前脉冲索引表中查找
	for i = 1, i <= pwtc do
		err = (pwt[i] - pulse)*100L/pwt[i];
		if math.abs(err) <= pwerr then
			-- 如果误差在允许范围内，则表示正确匹配，更新脉宽平均值
			pwt[i] = (pwt[i] * pwtn[i] + pulse) / (pwtn[i] + 1);
			pwtn[i]++;
			return i;
		end
	end

	// 没找到，要创建一个新的
	if(*pwtc < CCODE_MAX_PULSE_WIDTH_TYPE) {
		pwt[*pwtc] = pulse;
		pwtn[*pwtc] = 1;
		return (*pwtc)++;
	}

	// 脉宽索引表满，返回错误
	return -1;
}


/// @brief 扫描、统计脉宽种类、宽度平均值、置信度(coefficient)
/// @param pic 脉冲索引码
/// @param pb 脉冲缓冲区
/// @param pwerr 脉宽识别过程中，允许的误差(百分比)
/// @return 置信度
RcCodecError rc_pulse_index_code_parse(rc_pulse_buffer_t* pb, u8 pwerr, rc_pulse_index_code_t *pic, u8 *co) {
	u16* pulses = pb->pulses;
	u8 pwtn[CCODE_MAX_PULSE_WIDTH_TYPE];
	int j, pwti, err=0, maxErr=0;
	u16 pwold, pwnew;

	// 长度相同
	pic->plen = pb->plen;

	// 第 1 次扫描：分组、统计
	pic->pwtc = 0;
	for(j=0; j < pic->plen; j++) {
		pwti = matchPulse(pic->pwt, pwtn, &pic->pwtc, pwerr, pulses[j]);
		if(pwti < 0) { return RcCodecError_TOO_MANY_PULSE_TYPE; }
		pic->pwi[j] = pwti;
	}

	// 根据索引，把“原始脉冲值”换成“统计值”，并记录最大误差
	for(j=0; j < pic->plen; j++) {
		pwold = pulses[j];
		pwnew = pic->pwt[pic->pwi[j]];

		err = (pwnew - pwold) * 100L / pwnew;
		if(maxErr < err) { maxErr = err; }

		pulses[j] = pwnew;
	}

	// 第 2 次扫描：消除初次统计造成的误码
	pic->pwtc = 0;
	for(j=0; j < pic->plen; j++) {
		pwti = matchPulse(pic->pwt, pwtn, &pic->pwtc, pwerr, pulses[j]);
		if(pwti < 0) { return RcCodecError_TOO_MANY_PULSE_TYPE; }
		pic->pwi[j] = pwti;
	}

	// 再次统计最大误差
	for(j=0; j < pic->plen; j++) {
		pwold = pulses[j];
		pwnew = pic->pwt[pic->pwi[j]];

		err = (pwnew - pwold)*100L/pwnew;
		if(maxErr < err) { maxErr = err; }
	}

	//  * 10336 / 10000); // 时间校正 103.36%
	*co = 100 - maxErr;
	logd("Total %d index, %d pulses, %d%% coefficient\r\n", pic->pwtc, pic->plen, *co);
	return RcCodecError_OK;
}

local function main(argc, argv)
	local lmin, lmax, r0min, r0max, r1min, r1max = 65535, 0, 65535, 0, 65535, 0
	for i, lw, rw in zylib.igroup(argv, 2) do
		if i ~= 1 and i ~= argc / 2 then
			lw = tonumber(lw); rw = tonumber(rw);
			if lw < lmin then lmin = lw elseif lw > lmax then lmax = lw end
			if rw < rmin then rmin = rw elseif rw > rmax then rmax = rw end
			print(i-1, lw, rw, lw + rw)
		end
	end
	print(lmin, lmax, lmax-lmin)
	print(rmin, rmax, rmax-rmin)
end

main(#arg, arg)
